package io.framework.modules.air.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.framework.common.annotation.LogOperation;
import io.framework.common.exception.ErrorCode;
import io.framework.common.utils.ConvertUtils;
import io.framework.common.utils.Result;
import io.framework.common.validator.AssertUtils;
import io.framework.modules.air.dto.AirCheckExplainDTO;
import io.framework.modules.air.dto.AirDTO;
import io.framework.modules.air.dto.AirDayNumberDTO;
import io.framework.modules.air.dto.AirNdChangeDTO;
import io.framework.modules.air.entity.AirCheckExplainEntity;
import io.framework.modules.air.entity.AirDayNumberEntity;
import io.framework.modules.air.entity.AirEntity;
import io.framework.modules.air.entity.AirNdChangeEntity;
import io.framework.modules.air.service.AirCheckExplainService;
import io.framework.modules.air.service.AirDayNumberService;
import io.framework.modules.air.service.AirNdChangeService;
import io.framework.modules.air.service.AirService;
import io.framework.modules.air.utils.AirFileCommonUtil;
import io.framework.modules.station.dto.StationDTO;
import io.framework.modules.station.service.StationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * /**
 * 〈空气数据上传〉
 *
 * @Author GJQ
 * @Create 2020/5/20
 * @Since 1.0.0
 */
@RestController
@Api(tags = "空气站点监测数据上传")
@SuppressWarnings("all")
public class UploadAirDataController {

    @Value("${file.upload.path}")
    private String FILE_UPLOAD_PATH;

    Logger logger = LoggerFactory.getLogger(UploadAirDataController.class);

    @Autowired
    private AirService airService;

    @Autowired
    private AirDayNumberService airDayNumberService;

    @Autowired
    private AirNdChangeService airNdChangeService;

    @Autowired
    private StationService stationService;

    @Autowired
    private AirCheckExplainService airCheckExplainService;

    @GetMapping("air/upload/checkData")
    @ApiOperation("验证空气数据上传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "month", value = "时间月份 例：2020-03", paramType = "query", dataType = "Integer", required = true),
    })
    public Result checkData(@RequestParam Map<String, Object> params) {

        logger.info("=======================验证空气数据上传=======================");

        String month = params.get("month").toString();

        Boolean flag = airService.checkData(1,month);
        if (flag) {
            return new Result().error(ErrorCode.UPLOAD_FILE_CHECK);
        }
        return new Result();
    }

    @PostMapping("air/upload/datas/uploadFile")
    @ApiOperation("空气上传数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "1-城市站点-监测数据 2-旅游区站点-监测数据 3-城市-监测数据 4-城市－优良天数 5-城市-月均浓度与上月比较 6-城市-月均浓度与去年同期比 7-站点－审核情况说明", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "month", value = "时间月份 例：2020-03", paramType = "query", dataType = "String", required = true),
            @ApiImplicitParam(name = "multipartFile", value = "文件", paramType = "query", dataType = "String", required = true),
    })
    @LogOperation("上传空气站点监测数据")
    @RequiresPermissions("air:info:upload")
    public Result readAir(Integer type, String month, MultipartFile multipartFile) {
        AssertUtils.isBlank("type",ErrorCode.NOT_NULL);
        AssertUtils.isBlank("month",ErrorCode.NOT_NULL);
        String filename = multipartFile.getOriginalFilename();
        if(StringUtils.isEmpty(filename)){
            return new Result().error(ErrorCode.UPLOAD_FILE_EMPTY);
        }
        File file = new File(FILE_UPLOAD_PATH + DateUtil.format(new Date(), "yyyy-MM-dd"));
        if (!file.exists()) {
            file.mkdirs();
        }
        File excelFile = new File(file, File.separator + DateUtil.format(new Date(), "HHmmss") + filename.substring(filename.indexOf(".")));
        try {
            multipartFile.transferTo(excelFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String filePath = excelFile.getPath();

        List<AirDTO> airDTOList = new ArrayList<>();
        logger.info("=======================城市站点-监测数据=======================");
        List<AirDTO> cityStationList = AirFileCommonUtil.readAirData(0, month, filePath);
        if(CollectionUtils.isNotEmpty(cityStationList)){
            airDTOList.addAll(cityStationList);
        }
        logger.info("=======================旅游区站点-监测数据=======================");
        List<AirDTO> lvyouStationList = AirFileCommonUtil.readAirData(1, month, filePath);
        if(CollectionUtils.isNotEmpty(lvyouStationList)){
            airDTOList.addAll(lvyouStationList);
        }
        logger.info("=======================城市-监测数据=======================");
        List<AirDTO> cityMonitorList = AirFileCommonUtil.readAirData(2, month, filePath);
        if(CollectionUtils.isNotEmpty(cityMonitorList)){
            airDTOList.addAll(cityMonitorList);
        }
        logger.info("=======================城市-优良天数=======================");
        List<AirDayNumberDTO> youliangNumList = AirFileCommonUtil.readAirNumber(3,month, filePath);
        List<AirNdChangeDTO> airNdChangeDTOS = new ArrayList<>();
        logger.info("=======================城市-月均浓度与上月比较=======================");
        List<AirNdChangeDTO> huanbiList = AirFileCommonUtil.readAirNdChange(4, month, filePath);
        if(CollectionUtils.isNotEmpty(huanbiList)){
            airNdChangeDTOS.addAll(huanbiList);
        }
        logger.info("=======================城市-月均浓度与去年同期比=======================");
        List<AirNdChangeDTO> tongbiList = AirFileCommonUtil.readAirNdChange(5, month, filePath);
        if(CollectionUtils.isNotEmpty(tongbiList)){
            airNdChangeDTOS.addAll(tongbiList);
        }
        logger.info("=======================站点－审核情况说明=======================");
        List<AirCheckExplainDTO> airCheckExplainDTOS = AirFileCommonUtil.readAirCheckExplain(6, month, filePath);

        if(CollectionUtils.isNotEmpty(airDTOList) && CollectionUtils.isNotEmpty(youliangNumList) && CollectionUtils.isNotEmpty(airNdChangeDTOS) && CollectionUtils.isNotEmpty(airCheckExplainDTOS)){
            airDTOList.forEach(v -> {
                Map<String, Object> map = new HashMap<>(2);
                map.put("name", v.getStationName());
                map.put("type", 1);
                List<StationDTO> stationDTOS = stationService.getStationInfoByParams(map);
                if (stationDTOS != null && stationDTOS.size() > 0) {
                    v.setStationId(stationDTOS.get(0).getId());
                }
            });
            airCheckExplainDTOS.forEach(v -> {
                Map<String, Object> map = new HashMap<>(2);
                map.put("type", 1);
                map.put("name", v.getStationName());
                List<StationDTO> stationDTOS = stationService.getStationInfoByParams(map);
                if (CollectionUtils.isNotEmpty(stationDTOS)) {
                    v.setStationId(stationDTOS.get(0).getId());
                }
            });

            logger.info("=======================清理历史数据=======================");
            airService.deleteInfoByMonth(month);
            airService.insertBatch(ConvertUtils.sourceToTarget(airDTOList, AirEntity.class));
            airDayNumberService.insertBatch(ConvertUtils.sourceToTarget(youliangNumList, AirDayNumberEntity.class));
            airNdChangeService.insertBatch(ConvertUtils.sourceToTarget(airNdChangeDTOS, AirNdChangeEntity.class));
            airCheckExplainService.insertBatch(ConvertUtils.sourceToTarget(airCheckExplainDTOS, AirCheckExplainEntity.class));
        }else{
            return new Result().error(ErrorCode.UPLOAD_FILE_TYPE_NOTNULL);
        }
        return new Result().ok("上传成功");
    }
}
